package com.fin.zw.intelligentbot.service;

import com.fin.zw.intelligentbot.entity.CategoryLabel;
import com.fin.zw.intelligentbot.entity.QDialTask;
import com.fin.zw.intelligentbot.entity.QStrategyInfo;
import com.fin.zw.intelligentbot.entity.StrategyInfo;
import com.fin.zw.intelligentbot.enums.Status;
import com.fin.zw.intelligentbot.enums.TaskStatus;
import com.fin.zw.intelligentbot.model.request.StrategyRequest;
import com.fin.zw.intelligentbot.model.response.CategoryResponse;
import com.fin.zw.intelligentbot.model.response.StrategyInfoResponse;
import com.fin.zw.intelligentbot.model.response.StrategyResponse;
import com.fin.zw.intelligentbot.model.session.SessionModel;
import com.fin.zw.intelligentbot.repository.CategoryLabelRepository;
import com.fin.zw.intelligentbot.repository.DialTaskRepository;
import com.fin.zw.intelligentbot.repository.StrategyInfoRespository;
import com.querydsl.core.BooleanBuilder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;

@Service("strategyInfoService")
public class StrategyInfoService {

    @Autowired
    private StrategyInfoRespository strategyInfoRespository;

    @Autowired
    private CategoryLabelRepository categoryLabelRepository;

    @Autowired
    private CommonService commonService;

    @Autowired
    private DialTaskRepository dialTaskRepository;

    /**
     * 策略信息的查询
     *
     * @param name
     * @param categoryId
     * @param sessionModel
     * @param pageable
     * @return
     */
    public Page<StrategyResponse> getStrategyInfo(String name, String categoryId, SessionModel sessionModel, Pageable pageable) {
        BooleanBuilder builder = new BooleanBuilder();
        QStrategyInfo qStrategyInfo = QStrategyInfo.strategyInfo;
        builder.and(qStrategyInfo.status.eq(Status.START));
        if (StringUtils.isNotEmpty(sessionModel.getCompanyId())) {
            builder.and(qStrategyInfo.company.id.eq(sessionModel.getCompanyId()));
        }
        if (StringUtils.isNotEmpty(name)) {
            builder.and(qStrategyInfo.name.eq(name));
        }
        if (StringUtils.isNotEmpty(categoryId)) {
            builder.and(qStrategyInfo.categoryIds.contains(categoryId));
        }
        Page<StrategyInfo> infoPage = strategyInfoRespository.findAll(builder, pageable);
        Page<StrategyResponse> page = infoPage.map(strategyInfo -> {
            StrategyResponse response = new StrategyResponse();
            BeanUtils.copyProperties(strategyInfo, response);
            List<CategoryLabel> categoryLabels = new ArrayList<>();
            List<String> categoryIds = Arrays.asList(strategyInfo.getCategoryIds().split(","));
            for (String id : categoryIds) {
                Optional<CategoryLabel> optional = categoryLabelRepository.findById(id);
                if (optional.isPresent()) {
                    categoryLabels.add(optional.get());
                }
            }
            response.setCategoryLabels(categoryLabels);
            return response;
        });
        return page;
    }

    public List<StrategyInfoResponse> getStrategyInfoResponseList(SessionModel sessionModel) {
        List<StrategyInfoResponse> list = new ArrayList<>();
        BooleanBuilder builder = new BooleanBuilder();
        QStrategyInfo qStrategyInfo = QStrategyInfo.strategyInfo;
        builder.and(qStrategyInfo.status.eq(Status.START));
        if (StringUtils.isNotEmpty(sessionModel.getCompanyId())) {
            builder.and(qStrategyInfo.company.id.eq(sessionModel.getCompanyId()));
        }
        Iterator<StrategyInfo> iterator = strategyInfoRespository.findAll(builder).iterator();
        while (iterator.hasNext()) {
            StrategyInfo strategyInfo = iterator.next();
            StrategyInfoResponse response = new StrategyInfoResponse();
            BeanUtils.copyProperties(strategyInfo, response);
            List<CategoryResponse> categoryLabels = new ArrayList<>();
            List<String> categoryIds = Arrays.asList(strategyInfo.getCategoryIds().split(","));
            for (String id : categoryIds) {
                Optional<CategoryLabel> optional = categoryLabelRepository.findById(id);
                if (optional.isPresent()) {
                    CategoryResponse categoryResponse = new CategoryResponse();
                    BeanUtils.copyProperties(optional.get(), categoryResponse);
                    categoryLabels.add(categoryResponse);
                }
            }
            response.setCategoryLabels(categoryLabels);
            list.add(response);
        }
        return list;
    }

    /**
     * 查询对应的所有策略
     *
     * @param sessionModel
     * @return
     */
    public List<StrategyResponse> getStrategyList(SessionModel sessionModel) {
        List<StrategyResponse> list = new ArrayList<>();
        BooleanBuilder builder = new BooleanBuilder();
        QStrategyInfo qStrategyInfo = QStrategyInfo.strategyInfo;
        builder.and(qStrategyInfo.status.eq(Status.START));
        if (StringUtils.isNotEmpty(sessionModel.getCompanyId())) {
            builder.and(qStrategyInfo.company.id.eq(sessionModel.getCompanyId()));
        }
        Iterator<StrategyInfo> iterator = strategyInfoRespository.findAll(builder).iterator();
        while (iterator.hasNext()) {
            StrategyInfo strategyInfo = iterator.next();
            StrategyResponse response = new StrategyResponse();
            BeanUtils.copyProperties(strategyInfo, response);
            List<CategoryLabel> categoryLabels = new ArrayList<>();
            List<String> categoryIds = Arrays.asList(strategyInfo.getCategoryIds().split(","));
            for (String id : categoryIds) {
                Optional<CategoryLabel> optional = categoryLabelRepository.findById(id);
                if (optional.isPresent()) {
                    categoryLabels.add(optional.get());
                }
            }
            response.setCategoryLabels(categoryLabels);
            list.add(response);
        }
        return list;
    }
    /**
     * 策略的添加
     *
     * @param request
     * @param sessionModel
     */
    public void createStrategy(StrategyRequest request, SessionModel sessionModel) {
        StrategyInfo strategyInfo = new StrategyInfo();
        String categoryId = String.join(",", request.getCategoryIds());
        strategyInfo.setName(request.getName());
        strategyInfo.setCategoryIds(categoryId);
        strategyInfo.setCreateTime(new Date());
        strategyInfo.setRecycleCount(request.getRecycleCount());
        strategyInfo.setStatus(Status.START);
        strategyInfo.setCompany(commonService.getCompany(sessionModel));
        strategyInfoRespository.save(strategyInfo);
    }

    /**
     * 策略的修改
     *
     * @param request
     */
    public void updateStrategy(StrategyRequest request) {
        if (StringUtils.isEmpty(request.getId())) {
            throw new RuntimeException("策略id不能为空！");
        }
        if (!whetherUpdate(request.getId())) {
            throw new RuntimeException("该策略不允许修改");
        }
        Optional<StrategyInfo> optional = strategyInfoRespository.findById(request.getId());
        if (!optional.isPresent()) {
            throw new RuntimeException("没有对应的策略信息");
        }
        StrategyInfo strategyInfo = optional.get();
        String categoryId = String.join(",", request.getCategoryIds());
        strategyInfo.setCategoryIds(categoryId);
        strategyInfo.setName(request.getName());
        strategyInfoRespository.save(strategyInfo);
    }

    /**
     * 策略删除
     *
     * @param id
     */
    public void deleteStrategy(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new RuntimeException("策略id不能为空！");
        }
        if (!whetherUpdate(id)) {
            throw new RuntimeException("该策略不允许删除");
        }
        Optional<StrategyInfo> optional = strategyInfoRespository.findById(id);
        if (!optional.isPresent()) {
            throw new RuntimeException("该策略信息不存在");
        }
        StrategyInfo strategyInfo = optional.get();
        strategyInfo.setStatus(Status.STOP);
        strategyInfoRespository.save(strategyInfo);
    }

    /**
     * 根据策略id进行判断测试是否可以修改
     *
     * @param strategyId
     * @return
     */
    public boolean whetherUpdate(String strategyId) {
        BooleanBuilder builder = new BooleanBuilder();
        QDialTask qDialTask = QDialTask.dialTask;
        builder.and(qDialTask.strategyInfo.id.eq(strategyId));
        builder.and(qDialTask.status.ne(TaskStatus.FINISH));
        Integer count = Math.toIntExact(dialTaskRepository.count(builder));
        if (count > 0) {
            return false;
        } else {
            return true;
        }
    }
}
